package com.oracle.controller;

import com.alibaba.fastjson.JSON;
import com.oracle.common.R;
import com.oracle.entity.Oauser;
import com.oracle.service.OauserService;
import com.oracle.util.JJwtUtil;
import com.oracle.util.SMSUtil;
import com.oracle.util.VerifyCode;
import com.oracle.vo.req.OauserVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
public class LoginController {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private OauserService userService;

    //短信接口 发送验证码
    @GetMapping("/sendSms")
    public R sendSms(String mobile){

        //调用短信接口
        try {
            //生成手机验证码
            String code = (int) (Math.random() * 1000000) + "";
            System.out.println("短信验证码："+code);

            stringRedisTemplate.opsForValue().set("sysCode:"+mobile,code,3, TimeUnit.MINUTES);

            SMSUtil smsUtil = new SMSUtil();
            smsUtil.sendSMS(mobile,code);
        } catch (Exception e) {
            throw new RuntimeException(e);
//            return R.failed("发送失败");
        }

        return R.success("发送成功");
    }

    /* 获取验证码图片*/
    @RequestMapping("/verify")
    public void getVerificationCode(HttpServletResponse response, HttpServletRequest request) {

        try {

            int width = 200;

            int height = 69;

            BufferedImage verifyImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

            //生成对应宽高的初始图片

            String randomText = VerifyCode.drawRandomText(width, height, verifyImg);

            //单独的一个类方法，出于代码复用考虑，进行了封装。

            //功能是生成验证码字符并加上噪点，干扰线，返回值为验证码字符
//            request.getSession().setAttribute("verifyCode", randomText);

            stringRedisTemplate.opsForValue().set("sysCode",randomText,5, TimeUnit.MINUTES);

            response.setContentType("image/png");//必须设置响应内容类型为图片，否则前台不识别

            OutputStream os = response.getOutputStream(); //获取文件输出流

            ImageIO.write(verifyImg, "png", os);//输出图片流

            os.flush();

            os.close();//关闭流

        } catch (IOException e) {
            e.printStackTrace();

        }

    }

    /**
     * 手机验证码登录
     * @param mobile
     * @param code
     * @return
     */
    @GetMapping("/smsLogin")
    public R smsLogin(String mobile,String code){

        //1、获取短信验证码
        String sysCode = stringRedisTemplate.opsForValue().get("sysCode:" + mobile);
        Map<String, String> map = new HashMap<>();
        //2、验证码未失效
        if(!StringUtils.isEmpty(sysCode) && sysCode.equals(code)){
            //3、账号登录成功的用户信息 存入到security
            Oauser userByMobile = userService.findUserByMobile(mobile);

            //手机号为空 说明当前用户不存在 那么将该手机号 做注册
            if(!ObjectUtils.isEmpty(userByMobile)){
                //封装Authentication对象存入SecurityContextHolder
                //TODO 获取权限信息封装到Authentication中
//                UsernamePasswordAuthenticationToken authenticationToken =
//                        new UsernamePasswordAuthenticationToken(userByMobile,null,null);
//                SecurityContextHolder.getContext().setAuthentication(authenticationToken);

                //4、生成token
                String jsonString = JSON.toJSONString(userByMobile);
                String jwt = JJwtUtil.createJWT(jsonString);

                map.put("token",jwt);
                map.put("id",userByMobile.getId()+"");
                map.put("truename",userByMobile.getTruename());
                map.put("loginname",userByMobile.getLoginname());

                //把完整的用户信息存入redis  userid为key   用户信息为value
                stringRedisTemplate.opsForValue().set("login:"+userByMobile.getLoginname(),
                        JSON.toJSONString(userByMobile),2, TimeUnit.HOURS);


                return R.success(map);
            }else{
                //将该手机号 做注册
                    //1、前面讲过
                    //2、OA 不需要自己注册
            }

        }

        return R.failed(null);

    }


    /**
     * 账号密码登录
     * @param oauserVo
     * @return
     */
    @PostMapping("/user/login")
    public R login(@RequestBody OauserVo oauserVo) {

        //比对用户验证码是否正确
        String sysCode = stringRedisTemplate.opsForValue().get("sysCode");
        R failed = R.failed(null);
        //大小写不敏感
        if(sysCode.toUpperCase().equals(oauserVo.getCode().toUpperCase())){
            //登录逻辑
            try {
                return R.success(userService.login(oauserVo));
            } catch (Exception e) {

                failed.setMsg("登录失败");
                return failed;
            }
        }

        failed.setMsg("验证码不正确!");
        return failed;
    }

    @GetMapping("/")
    public String index() {
        return "welcome OAS!";
    }

    @PostMapping("/register")
    public R register(@RequestBody Oauser oauser) {

        userService.register(oauser);

        return R.success(null);
    }

    @GetMapping("/loginOut")
    public R loginOut(String loginname) {

        //获取SecurityContextHolder中的用户id
//        UsernamePasswordAuthenticationToken authenticationToken =
//                (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();

        //获取当前登录用户
//        Oauser oauser = (Oauser) authenticationToken.getPrincipal();
//        Integer eid = oauser.getId();

        stringRedisTemplate.delete("login:" + loginname);

        return R.success("退出成功。");
    }

}

